<script src="../../../resources/js-test.js"></script>
<div id='touchtarget' style='width: 50; height: 50'></div>
<script>
description("This test checks that we correctly update the touch event handler count as event handlers are added and removed");

debug("Test addEventListener/removeEventListener on the document.");
(function() {
    var listener = function() { }

    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '0');
    document.addEventListener('touchstart', listener, true);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');
    document.addEventListener('touchmove', listener, true);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '2');
    document.addEventListener('touchstart', listener, false);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '3');
    document.removeEventListener('touchmove', listener, true);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '2');
    document.removeEventListener('touchstart', listener, true);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');

    // Try removing the capturing listener again.
    document.removeEventListener('touchstart', listener, true);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');
    document.removeEventListener('touchmove', listener, true);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');

    document.removeEventListener('touchstart', listener, false);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '0');
})();

debug("Test setting touch handlers on the document.");
(function() {
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '0');
    document.ontouchstart = function() { }
    document.ontouchmove = function() {}
    document.ontouchend = function() {}
    document.ontouchcancel = function() {}
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '2');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '2');
    document.ontouchstart = function() { }
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '2');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '2');
    document.ontouchstart = null;
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '2');
    document.ontouchstart = null;
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '2');
    document.ontouchend = null;
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '1');
    document.ontouchmove = null;
    document.ontouchcancel = null;
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '0');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '0');
})();

debug("Test addEventListener/removeEventListener on the window.");
(function() {
    var listener = function() { }

    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '0');
    window.addEventListener('touchstart', listener, true);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');
    window.addEventListener('touchmove', listener, true);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '2');
    window.addEventListener('touchstart', listener, false);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '3');
    window.removeEventListener('touchmove', listener, true);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '2');
    window.removeEventListener('touchstart', listener, true);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');

    // Try removing the capturing listener again.
    window.removeEventListener('touchstart', listener, true);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');
    window.removeEventListener('touchmove', listener, true);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');

    window.removeEventListener('touchstart', listener, false);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '0');
})();

debug("Test setting touch handlers on the window.");
(function() {
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '0');
    window.ontouchstart = function() { }
    window.ontouchmove = function() {}
    window.ontouchend = function() {}
    window.ontouchcancel = function() {}
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '2');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '2');
    window.ontouchstart = function() { }
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '2');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '2');
    window.ontouchstart = null;
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '2');
    window.ontouchstart = null;
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '2');
    window.ontouchend = null;
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '1');
    window.ontouchmove = null;
    window.ontouchcancel = null;
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '0');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '0');
})();

debug("Test addEventListener/removeEventListener on a div.");
(function() {
    var listener = function() { }
    var div = document.getElementById('touchtarget');

    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '0');
    div.addEventListener('touchstart', listener, true);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');
    div.addEventListener('touchmove', listener, true);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '2');
    div.addEventListener('touchstart', listener, false);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '3');
    div.removeEventListener('touchmove', listener, true);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '2');
    div.removeEventListener('touchstart', listener, true);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');

    // Try removing the capturing listener again.
    div.removeEventListener('touchstart', listener, true);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');
    div.removeEventListener('touchmove', listener, true);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');

    div.removeEventListener('touchstart', listener, false);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '0');
})();

debug("Test setting touch handlers on a div.");
(function() {
    var div = document.getElementById('touchtarget');

    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '0');
    div.ontouchstart = function() { }
    div.ontouchmove = function() { }
    div.ontouchend = function() { }
    div.ontouchcancel = function() { }
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '2');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '2');
    div.ontouchstart = function() { }
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '2');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '2');
    div.ontouchstart = null;
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '2');
    div.ontouchstart = null;
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '2');
    div.ontouchend = null;
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '1');
    div.ontouchmove = null;
    div.ontouchcancel = null;
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '0');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '0');
})();

debug("Test redudant addEventListener on a div.");
(function() {
    var listener = function() { }
    var div = document.getElementById('touchtarget');

    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '0');
    div.addEventListener('touchstart', listener, false);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');
    div.addEventListener('touchstart', listener, false);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');

    div.removeEventListener('touchstart', listener, false);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '0');
})();


debug("Test addEventListener/removeEventListener on a new div.");
(function() {
    var div = document.createElement('div');
    var touchtarget = document.getElementById('touchtarget');
    var listener = function() { }

    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '0');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '0');

    div.addEventListener('touchstart', listener, true);
    div.addEventListener('touchmove', listener, true);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '2');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '0');

    touchtarget.appendChild(div);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '2');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '0');

    div.addEventListener('touchend', listener, true);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '2');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '1');

    div.removeEventListener('touchstart', listener, true);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');

    touchtarget.removeChild(div);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');

    div.removeEventListener('touchmove', listener, false);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');

    div.removeEventListener('touchmove', listener, true);
    div.removeEventListener('touchend', listener, true);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '0');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '0');
})();

debug("Test setting touch handlers on a new div.");
(function() {
    var div = document.createElement('div');
    var touchtarget = document.getElementById('touchtarget');

    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '0');

    div.ontouchstart = function() { }
    div.ontouchmove = function() { }
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '2');

    touchtarget.appendChild(div);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '2');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '0');

    div.ontouchend = function() { }
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '2');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '1');

    div.ontouchstart = null;
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '1');

    touchtarget.removeChild(div);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '1');

    div.ontouchend = null;
    div.ontouchmove = null;
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '0');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '0');
})();

var nestedDocument;

debug("Test that nested Documents' touch handlers are properly tracked in their parent Document.");
(function() {
    var iframe = document.createElement('iframe');
    var touchtarget = document.getElementById('touchtarget');
    touchtarget.ontouchend = function() {};

    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '0');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '1');

    touchtarget.appendChild(iframe);

    nestedDocument = iframe.contentWindow.document;
    nestedDocument.open('text/html', 'replace');
    nestedDocument.write('<!DOCTYPE html>\n<script>\nwindow.ontouchstart=function(){};\n</' + 'script>\n' +
        '<div id=twoHandlers ontouchmove="function(){}" ontouchcancel="function(){}"></div>');
    shouldBe('internals.touchStartOrMoveEventHandlerCount(nestedDocument)', '2');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(nestedDocument)', '2');
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '2');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '2');

    nestedDocument.write('<script>window.ontouchstart=undefined</' + 'script>\n');
    shouldBe('internals.touchStartOrMoveEventHandlerCount(nestedDocument)', '1');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(nestedDocument)', '2');
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '2');

    nestedDocument.write('<script>document.addEventListener("touchmove", function(){});</' + 'script>\n');
    shouldBe('internals.touchStartOrMoveEventHandlerCount(nestedDocument)', '2');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(nestedDocument)', '2');
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '2');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '2');
    
    nestedDocument.write('<script>document.getElementById("twoHandlers").remove();</' + 'script>\n');
    gc();
    shouldBe('internals.touchStartOrMoveEventHandlerCount(nestedDocument)', '1');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(nestedDocument)', '1');
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '1');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '1');
    nestedDocument.close();    

    touchtarget.removeChild(iframe);
    shouldBe('internals.touchStartOrMoveEventHandlerCount(document)', '0');
    shouldBe('internals.touchEndOrCancelEventHandlerCount(document)', '1');
})();
</script>
</body>
